﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace KeywordsMoveFiles400
{
    public partial class FrmMain : Form
    {
        private Thread _thread;
        public FrmMain()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
            this.FormClosing += (ss, ee) =>
            {
                if (_thread != null && _thread.IsAlive) _thread.Abort();
            };
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            new TextBoxDragDrop(txtFilesPath);
            new TextBoxDragDrop(txtSavePath1);
            new TextBoxDragDrop(txtSavePath2);
            new TextBoxDragDrop(txtSavePath3);
            new TextBoxDragDrop(txtSavePath4);

            new TextBoxDragDrop(txtKeywordsFile1, true, new List<string>() { ".txt" });
            new TextBoxDragDrop(txtKeywordsFile2, true, new List<string>() { ".txt" });
            new TextBoxDragDrop(txtKeywordsFile3, true, new List<string>() { ".txt" });
            new TextBoxDragDrop(txtKeywordsFile4, true, new List<string>() { ".txt" });

            initialize();
        }
        private void initialize()
        {
            ConfigInfo config = ConfigMgr.Get();
            txtFilesPath.Text = config.FilesPath;

            txtSavePath1.Text = config.SavePath1;
            txtSavePath2.Text = config.SavePath2;
            txtSavePath3.Text = config.SavePath3;
            txtSavePath4.Text = config.SavePath4;

            txtKeywordsFile1.Text = config.KeywordsFile1;
            txtKeywordsFile2.Text = config.KeywordsFile2;
            txtKeywordsFile3.Text = config.KeywordsFile3;
            txtKeywordsFile4.Text = config.KeywordsFile4;
        }

        private bool saveConfig()
        {
            ConfigInfo config = new ConfigInfo();
            config.FilesPath = txtFilesPath.Text.Trim();

            config.SavePath1 = txtSavePath1.Text.Trim();
            config.SavePath2 = txtSavePath2.Text.Trim();
            config.SavePath3 = txtSavePath3.Text.Trim();
            config.SavePath4 = txtSavePath4.Text.Trim();

            config.KeywordsFile1 = txtKeywordsFile1.Text.Trim();
            config.KeywordsFile2 = txtKeywordsFile2.Text.Trim();
            config.KeywordsFile3 = txtKeywordsFile3.Text.Trim();
            config.KeywordsFile4 = txtKeywordsFile4.Text.Trim();

            try
            {
                if (!Directory.Exists(config.FilesPath)) throw new Exception("目录位置不存在");
                checkFileAndFolderExisting(config.KeywordsFile1, config.SavePath1, 1);
                checkFileAndFolderExisting(config.KeywordsFile2, config.SavePath2, 2);
                checkFileAndFolderExisting(config.KeywordsFile3, config.SavePath3, 3);
                checkFileAndFolderExisting(config.KeywordsFile4, config.SavePath4, 4);
                ConfigMgr.Save(config);
                return true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }
        }
        private static void checkFileAndFolderExisting(string keyworksFile, string savePath, int index)
        {
            if (keyworksFile != "" && savePath != "")
            {
                if (!File.Exists(keyworksFile))
                {
                    throw new Exception($"关键词{index}文件不存在");
                }
                if (!Directory.Exists(savePath))
                {
                    throw new Exception($"指定位置{index}不存在");
                }
            }
        }

        private static void chooseFolder(TextBox textBox)
        {
            FolderBrowserDialog dlg = new FolderBrowserDialog();
            string oldPath = textBox.Text.Trim();
            if (Directory.Exists(oldPath))
                dlg.SelectedPath = oldPath;
            if (dlg.ShowDialog() != DialogResult.OK) return;
            textBox.Text = dlg.SelectedPath;
        }
        private static void chooseTxtFile(TextBox textBox)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            string oldFileName = textBox.Text.Trim();
            if (File.Exists(oldFileName))
                dlg.FileName = oldFileName;
            dlg.Filter = "文本文档(*.txt)|*.txt";
            if (dlg.ShowDialog() != DialogResult.OK) return;
            textBox.Text = dlg.FileName;
        }
        private void btnFilesPath_Click(object sender, EventArgs e)
        {
            chooseFolder(txtFilesPath);
        }

        private void btnKeywordsFile1_Click(object sender, EventArgs e)
        {
            chooseTxtFile(txtKeywordsFile1);
        }

        private void btnSavePath1_Click(object sender, EventArgs e)
        {
            chooseFolder(txtSavePath1);
        }

        private void btnKeywordsFile2_Click(object sender, EventArgs e)
        {
            chooseTxtFile(txtKeywordsFile2);
        }

        private void btnSavePath2_Click(object sender, EventArgs e)
        {
            chooseFolder(txtSavePath2);
        }

        private void btnKeywordsFile3_Click(object sender, EventArgs e)
        {
            chooseTxtFile(txtKeywordsFile3);
        }

        private void btnSavePath3_Click(object sender, EventArgs e)
        {
            chooseFolder(txtSavePath3);
        }

        private void btnKeywordsFile4_Click(object sender, EventArgs e)
        {
            chooseTxtFile(txtKeywordsFile4);
        }

        private void btnSavePath4_Click(object sender, EventArgs e)
        {
            chooseFolder(txtSavePath4);
        }

        private void btnExecute_Click(object sender, EventArgs e)
        {
            if (!saveConfig()) return;
            _thread = new Thread(new ThreadStart(workService));
            _thread.Start();
        }
        private void working(string filesPath, string keywordFile, string savePath)
        {
            if (!Directory.Exists(filesPath)) return;
            if (!File.Exists(keywordFile)) return;
            if (!Directory.Exists(savePath)) return;

            string[] files = Directory.GetFiles(filesPath, "*.*", SearchOption.AllDirectories);
            Encoding encoding = FileEncoding.Get(keywordFile);
            string content = File.ReadAllText(keywordFile, encoding);
            string[] keywords = content.Trim().Split(new char[] { '|', '｜' }, StringSplitOptions.RemoveEmptyEntries);
            HashSet<string> set = new HashSet<string>();
            foreach (string keyword in keywords)
            {
                if (keyword.Trim() == "") continue;
                set.Add(keyword);
            }
            HashSet<string> matchedFiles = new HashSet<string>();
            foreach (string fn in files)
            {
                string name = Path.GetFileNameWithoutExtension(fn);
                foreach (string keyword in set)
                {
                    if (name.Contains(keyword))
                    {
                        matchedFiles.Add(fn);
                        break;
                    }
                }
            }
            pbarSub.Value = 0;
            pbarSub.Minimum = 0;
            pbarSub.Maximum = matchedFiles.Count;
            foreach (string fn in matchedFiles)
            {
                pbarSub.Value += 1;
                string destFileName = Path.Combine(savePath, Path.GetFileName(fn));
                if (File.Exists(destFileName))
                    File.Delete(destFileName);
                File.Move(fn, destFileName);
            }
        }
        private void workService()
        {
            try
            {
                foreach (Control control in this.Controls) control.Enabled = false;
                pbarMain.Enabled = true;
                this.Cursor = Cursors.WaitCursor;
                ConfigInfo config = ConfigMgr.Get();
                pbarMain.Value = 0;
                pbarMain.Minimum = 0;
                pbarMain.Maximum = 4;

                pbarMain.Value += 1;
                working(config.FilesPath, config.KeywordsFile1, config.SavePath1);
                pbarMain.Value += 1;
                working(config.FilesPath, config.KeywordsFile2, config.SavePath2);
                pbarMain.Value += 1;
                working(config.FilesPath, config.KeywordsFile3, config.SavePath3);
                pbarMain.Value += 1;
                working(config.FilesPath, config.KeywordsFile4, config.SavePath4);

                MessageBox.Show("执行完成", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (ThreadAbortException) { }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            finally
            {
                foreach (Control control in this.Controls) control.Enabled = true;
                this.Cursor = Cursors.Default;
            }
        }
    }
}
